
#ifndef BASE_H_
#define BASE_H_

#include <BWAPI.h>
#include <list>
#include <map>


#define RESOURCE_BOUND_X 15*TILE_SIZE
#define RESOURCE_BOUND_Y 12*TILE_SIZE

struct MinPatch
{
	BWAPI::Unit* mineral;
	int resourceGroupId;
	int mining;
};

struct Geyser
{
	BWAPI::Unit* refinery;
	BWAPI::Unit* geyser;
	int resourceGroupId;
	int gathering;
};

enum BASE
{
	BASE1,
	BASE2,
	BASE3,
	BASE4,
	BASE5,
	BASE6,
	BASE7,
	BASE8,
	BASE9
};


class Base
{
public:
	Base(BWAPI::TilePosition loc, BWAPI::Unit* cc, std::list<BWAPI::Unit*>* incWorkers = NULL, bool isMyBase = true);
	void AddBuilding(BWAPI::Unit* building);
	void AddUnit(BWAPI::Unit* unit);
	bool RemoveUnit(BWAPI::Unit* unit);
	bool RemoveBuilding(BWAPI::Unit* unit);
	void AddWorker(BWAPI::Unit* worker);
	void Update();

	std::map<BWAPI::UnitType, std::list<BWAPI::TilePosition>>*	GetEnemyBuildingLocations()	{	return &enemyBuildingPositions;	}


	bool NeedMoreWorkers()	{	return needMoreWorkers;	}
	bool NeedMoreGas();
	bool DeleteThisBase()	{	return toDelete;	}

	BWAPI::TilePosition	GetBaseLocation()	{	return location; }
	BWAPI::Position	GetBaseLocationPos()	{	return BWAPI::Position(location.x()*TILE_SIZE,location.y()*TILE_SIZE); }
	//Returns an array of two positions that define a 2d bouding box for this base
	BWAPI::Position* GetBaseBoundingBox();
	BWAPI::Unit* GetCC()	{	return mainCommandCenter;	}
	std::list<BWAPI::Unit*>* GetDamagedBuildings();
	std::list<BWAPI::Unit*>* GetIdleBuildings();
	std::list<BWAPI::Unit*>* GetBuildingsByType(BWAPI::UnitType type);
	int GetBuildingsCount();
	std::list<BWAPI::Unit*>* GetUnitsByType(BWAPI::UnitType type);
	std::list<MinPatch*>* GetMinerals()	{	return &minerals;	}
	std::list<Geyser*>* GetGeysers()	{	if(geysers.size() > 0) return &geysers;
											return NULL;	}

	int GetLastCountOfBuildings();
	void DecLastCountOfBuildings();	//will decrement the counter by 3.


private:
	/////Buildings//////////////////////////

	std::map<BWAPI::UnitType, std::list<BWAPI::Unit*>> buildingLookup;
	std::map<BWAPI::UnitType, std::list<BWAPI::Unit*>> unitLookup;
	std::map<BWAPI::UnitType, std::list<BWAPI::TilePosition>> enemyBuildingPositions;
	
	std::list<MinPatch*> minerals;
	std::list<Geyser*> geysers;

	std::set<BWAPI::Unit*> trainingUnits;
	std::list<BWAPI::Unit*> buildingsTrainingUnits;

	BWAPI::Unit* mainCommandCenter;

	BWAPI::TilePosition location;
	unsigned int remainingLocalMinerals;
	unsigned int remainingLocalGas;
	bool needMoreWorkers;

	void BuildLocalResourceList();

	bool isEnemyBase;
	bool toDelete;

	bool isResourceInRange(BWAPI::Unit* res, BWAPI::Position &pos);

	int LastCountOfBuildings;
};

#endif
